package paintball;

import game.Constants;
import game.GameObject;
import game.Projectile;
import game.Scoreboard;
import game.TwistyBasicGameState;

import java.util.ArrayList;
import org.newdawn.slick.Color;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.Input;
import org.newdawn.slick.KeyListener;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.state.StateBasedGame;

import vision.Vision;

import controllers.PlayerController;
import controllers.ProjectileController;

public class PaintballGame extends TwistyBasicGameState implements KeyListener {
	// Display properties
	private Color bgcolor = new Color(0, 0, 0);

	private boolean showScores = false;
	
	private PaintballPowerup powerup;
	private int step = 0;
	private int countdown = 500;
	
	// Images
	private Image projectileimg;
	private Image playerimg;
	private Image powerupimg;
	
	private int renderPlayerImgModifier = 0;
	
	public PaintballGame(Vision vision) {
		super(vision);
	}

	// Player List
	public ArrayList<PaintballPlayer> players() throws Exception {
		return PlayerController.getPlayers();
	}

	@Override
	public void render(GameContainer arg0, StateBasedGame game, Graphics g) throws SlickException {
		super.render(arg0, game, g);
		try {
			
			g.setBackground(bgcolor);
			if (players().size() > 0) {
				for (PaintballPlayer p : players()) {
					if(p != null){
						
						this.playerimg = new Image(p.curImgPath());
						g.rotate((p.getX() + (p.getWidth() / 2)),
								(p.getY() + (p.getHeight() / 2)),
								(float) p.getRotation());
						if(p.powerUp3 && renderPlayerImgModifier < 2){
							g.drawImage(this.playerimg, p.getX(), p.getY());
						}
						else if(!p.powerUp3){
							g.drawImage(this.playerimg, p.getX(), p.getY());
						}
						g.resetTransform();
						g.drawString(p.getPlayerName(), p.getX(),
								p.getY() + p.getHeight()+5);
						if(p.powerUp3){
							this.renderPlayerImgModifier++;
							if(renderPlayerImgModifier > 4){
								renderPlayerImgModifier = 0;
							}
						}
					}
				}
			}

			try{
				for(Projectile pb : ProjectileController.getProjectiles()){
					if(pb.isActive()){
						g.drawImage(this.projectileimg, pb.getX(), pb.getY());
					}
				}
			}catch(Exception e){
				
			}
			
			if(this.powerup != null && this.powerup.isActive()){
				powerupimg = new Image(powerup.curImgPath());
				g.rotate(powerup.getX()+16, powerup.getY()+16, (float) powerup.getRotation());
				g.drawImage(powerupimg, powerup.getX(), powerup.getY());
				g.resetTransform();
			}
			
			/*
			for (int y = 0; y < this.map.getHeight(); y++) {
				for (int x = 0; x < this.map.getWidth(); x++) {
					if (this.map.hasPointAtLocation(x, y)) {
						g.drawRect(x, y, 1, 1);
					}
				}
			}*/
			if (showScores) {
				g.drawString(Scoreboard.getScoresAsString(), 20, 20);
			}
			if(gameIsOver()){
				g.setColor(Color.green);
				g.drawString("WINNER: " + Scoreboard.topPlayer(), Constants.screenWidth/2, Constants.screenHeight/2);
				g.setColor(Color.white);
			}
		} catch (Exception e) {
			return;
		}
	}

	public boolean gameIsOver(){
		for(String key: Scoreboard.getScores().keySet()){
			if(Scoreboard.getScores().get(key) == Constants.maxKillAmount){
				return true;
			}
		}
		return false;
	}
	
	@Override
	protected void goToMenu_event(){
		Scoreboard.resetAllScores();
		ProjectileController.removeAllProjectiles();
		try {
			for(PaintballPlayer p: PlayerController.getPlayers()){
				p.respawn(this.map);
			}
		} catch (Exception e) {
		}
	}
	
	@Override
	public void init(GameContainer arg0, StateBasedGame arg1) throws SlickException {
		this.playerimg = new Image("res/paintballplayer.gif");
		this.projectileimg = new Image("res/projectile.png");

	}

	@Override
	public void update(GameContainer arg0, StateBasedGame game, int arg1) throws SlickException {
		super.update(arg0, game, arg1);
		step++;
		
		try {
			if(step%Constants.timeBetweenNewPowerUp == 0){
				double rnd = (Math.random()*5);
				
				if(rnd < 2){
					powerup = new PaintballPowerup((int)(Math.random()*(Constants.screenWidth-32))+32, (int) (Math.random()*(Constants.screenHeight-32))+32, 1);
				}else if( rnd >= 2 && rnd < 4){
					powerup = new PaintballPowerup((int)(Math.random()*(Constants.screenWidth-32))+32, (int) (Math.random()*(Constants.screenHeight-32))+32, 2);
				}else if( rnd >= 4){
					powerup = new PaintballPowerup((int)(Math.random()*(Constants.screenWidth-32))+32, (int) (Math.random()*(Constants.screenHeight-32))+32, 3);
				}
			}
			if(powerup != null && powerup.isActive()){
				powerup.step();
			}
			
			for (PaintballPlayer p : players()) {
				if (p != null) {
					if (p.getX() < 0 || p.getY() < 0) {
						p.setX((int) (Math.random() * Constants.screenWidth));
						p.setY((int) (Math.random() * Constants.screenHeight));
					}
					if ((int)p.getDesRotation() != (int)p.getRotation()){
						
						int difference = ((int)p.getDesRotation() - (int)p.getRotation());
						if(((difference < p.getRotationSpeed()) &&  difference > 0 ) || ((difference > (p.getRotationSpeed()*-1)) &&  difference < 0 )){
							p.setRotation(p.getDesRotation());
						}else {	
							if((difference+360)%360 < 180){
								p.setRotation(p.getRotation() + p.getRotationSpeed());	
							} else {
								p.setRotation(p.getRotation() + (p.getRotationSpeed()*-1));	
							}							

						}
					}					
					
					if (p.state == GameObject.State.DEAD) {
						p.currentRespawnTime--;
						if (p.currentRespawnTime < 0) {
							p.respawn(map);
							p.currentRespawnTime = p.getRespawnTime();
						}
					}

					if(p.isActive()){
						p.stepAction();
						if(p.move){
							p.move(map);
							p.collisionCheck(powerup);
							try{
								p.collisionCheck(PlayerController.getPlayers());
							}catch(Exception e){
							}
						}
					}
					
					if (p.healthUpdated) {
						p.send(0);
					}
				}
			}
			try{
			for(Projectile p: ProjectileController.getProjectiles()){
				if(p.isActive()){
					p.step(this.map, this.players());
				}
			}
			ProjectileController.checkRemove();
			}catch(Exception e){
				
			}
		} catch (Exception e) {
			e.printStackTrace();
			return;
		}
		if(gameIsOver()){
			countdown--;
			if(countdown == 0){
				countdown = 500;
				Scoreboard.resetAllScores();
				goToMenu = true;
			}
			return;
		}
		
	}

	@Override
	public void keyPressed(int key, char c) {
		super.keyPressed(key, c);
		if (key == Input.KEY_S) {			
			this.showScores = !showScores;
		}
	}

	@Override
	public int getID() {
		// TODO Auto-generated method stub
		return Constants.paintballGame;
	}

}
